package cn.kent.service;

import cn.kent.common.Message;
import cn.kent.common.MessageStorage;
import cn.kent.common.MessageType;
import cn.kent.util.DateUtil;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;

/**
 * 服务端和客户端连接的线程
 */
public class ServerConnectClientThread extends Thread {
    private Socket socket;
    private String userId;

    public ServerConnectClientThread(Socket socket, String userId) {
        this.socket = socket;
        this.userId = userId;
    }

    public Socket getSocket() {
        return this.socket;
    }

    @Override
    public void run() {// 这里线程处于run状态，可以发送/接收消息
        while (true) {
            try {
                System.out.println("服务端和客户端保持通信" + userId + "，读取数据...");
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                Message message = (Message) ois.readObject();
                // 根据message类型，
                if (message.getMsgType().equals(MessageType.MESSAGE_GET_ONLINE_FRIEND)) {
                    /*在线用户列表字符串格式(空格分隔): 100 200 太上老君*/
                    System.out.println(message.getSender() + "想要在线用户列表");
                    String onlineUsers = ManageClientThreads.getOnlineUsers();

                    // 返回message
                    Message msg = new Message();
                    msg.setMsgType(MessageType.MESSAGE_RET_ONLINE_FRIEND);
                    msg.setContent(onlineUsers);
                    msg.setSender("Server");
                    msg.setGetter(message.getSender());
                    msg.setSendTime(DateUtil.getNowDateStr());

                    // 返回客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(msg);

                } else if (message.getMsgType().equals(MessageType.MESSAGE_COMM_MES)) {
                    // 实现消息转发
                    ServerConnectClientThread clientThread = ManageClientThreads.getClientThread(message.getGetter());
                    if (clientThread == null) { // 未登录，将消息暂存,用户登录的时候进行读取返回
                        message.setOffLineBool(true); // 是离线消息
                        MessageStorage.addMessageStorage(message);
                        continue;
                    }
                    // 得到对应socket的对象输出流，将message对象转发给指定的客户端
                    ObjectOutputStream oos = new ObjectOutputStream(clientThread.socket.getOutputStream());
                    oos.writeObject(message);
                } else if (message.getMsgType().equals(MessageType.MESSAGE_TO_ALL_MES)) {
                    HashMap<String, ServerConnectClientThread> map = ManageClientThreads.getMap();
                    for (String k : map.keySet()) {
                        if (k.equals(userId)) continue;
                        ObjectOutputStream oos = new ObjectOutputStream(map.get(k).socket.getOutputStream());
                        oos.writeObject(message);
                    }
                } else if (message.getMsgType().equals(MessageType.MESSAGE_CLIENT_EXIT)) {
                    // 将客户端线程从集合中删除
                    ManageClientThreads.removeServerConnectClientThread(message.getSender());
                    socket.close(); // 关闭连接
                    System.out.println(userId + " 退出系统");
                    // 退出循环
                    break;
                } else if (message.getMsgType().equals(MessageType.MESSAGE_FILE_MES)) {
                    // 根据getterId获取到对应线程，将message转发
                    ServerConnectClientThread clientThread = ManageClientThreads.getClientThread(message.getGetter());
                    // 未登录，将消息暂存到map中
                    if (clientThread == null) {
                        message.setOffLineBool(true);
                        MessageStorage.addMessageStorage(message);
                        continue;
                    }
                    ObjectOutputStream oos = new ObjectOutputStream(clientThread.getSocket().getOutputStream());
                    oos.writeObject(message);
                } else {
                    // 其他类型的暂时不处理
                    System.out.println("其他类型的暂时不处理...");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}
